package org.garbagecan.quartzstudy.cron;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import junit.framework.Assert;

import org.quartz.CronExpression;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.CronCalendar;

public class TestCronExcpression {
	public static void test() throws Exception {
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();

		CronCalendar cal = new CronCalendar("0/3 * * * * ?");
		// CronCalendar cal = new CronCalendar("1/3 * * * * ?");
		scheduler.addCalendar("cal", cal, true, true);

		JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myjob","mygroup").build();

		Trigger trigger1 = TriggerBuilder.newTrigger()
				.withIdentity("trigger1", "group1")
				.forJob(jobDetail)
				.startNow()
				.withPriority(5)
				.withSchedule(CronScheduleBuilder
					.cronSchedule("0/3 * * * * ?"))
				.build();
		Trigger trigger2 = TriggerBuilder.newTrigger()
				.withIdentity("trigger1", "group1")
				.forJob(jobDetail)
				.startNow()
				.withPriority(5)
				.withSchedule(CronScheduleBuilder
					.cronSchedule("0/2 * * * * ?"))
				.build();
		
		scheduler.scheduleJob(jobDetail, trigger1);
		scheduler.scheduleJob(jobDetail, trigger2);

		scheduler.start();
	}

	public static void case1() throws Exception {
		print("case1: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 12 5 2 2 2007";
		String s22 = "0 0 13 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 12:00:00");
		Date date22 = parseToDate("2007-02-05 13:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertTrue(ce13.isSatisfiedBy(date21));
		Assert.assertTrue(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case21() throws Exception {
		print("case21: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 0 5 2 2 2007";
		String s22 = "0 0 7 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 00:00:00");
		Date date22 = parseToDate("2007-02-05 07:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertFalse(ce13.isSatisfiedBy(date21));
		Assert.assertFalse(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case22() throws Exception {
		print("case22: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 18 5 2 2 2007";
		String s22 = "0 0 23 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 18:00:00");
		Date date22 = parseToDate("2007-02-05 23:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertFalse(ce13.isSatisfiedBy(date21));
		Assert.assertFalse(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case31() throws Exception {
		print("case31: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 0 5 2 2 2007";
		String s22 = "0 0 12 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 00:00:00");
		Date date22 = parseToDate("2007-02-05 12:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertFalse(ce13.isSatisfiedBy(date21));
		Assert.assertTrue(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case32() throws Exception {
		print("case32: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 12 5 2 2 2007";
		String s22 = "0 0 23 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 12:00:00");
		Date date22 = parseToDate("2007-02-05 23:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertTrue(ce13.isSatisfiedBy(date21));
		Assert.assertFalse(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case4() throws Exception {
		print("case4: -------------------------------");
		// reoccurrence
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 17 ? * * *";
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 8 5 2 2 2007";
		String s22 = "0 0 18 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 8:00:00");
		Date date22 = parseToDate("2007-02-05 18:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);

		Assert.assertFalse(ce13.isSatisfiedBy(date21));
		Assert.assertFalse(ce13.isSatisfiedBy(date22));
		print(ce13.isSatisfiedBy(date21));
		print(ce13.isSatisfiedBy(date22));
	}

	public static void case9() throws Exception {
		print("case9: -------------------------------");
		// reoccurrence
		// 9:00-23:59
		String s11 = "0 0 9 ? * * *";
		String s12 = "0 0 8 ? * * *"; // next day
		CronExpression ce11 = new CronExpression(s11);
		CronExpression ce12 = new CronExpression(s12);

		String s13 = "* * 9-17 ? * * *";
		CronExpression ce13 = new CronExpression(s13);

		// once only
		String s21 = "0 0 8 5 2 2 2007";
		String s22 = "0 0 18 5 2 2 2007";
		Date date21 = parseToDate("2007-02-05 8:00:00");
		Date date22 = parseToDate("2007-02-05 18:00:00");
		CronExpression ce21 = new CronExpression(s21);
		CronExpression ce22 = new CronExpression(s22);
	}

	public static void print(Object obj) {
		System.out.println(obj);
	}

	public static Date parseToDate(String s) throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = df.parse(s);
		return date;
	}
}
